package sad.dao;

import com.db4o.ObjectSet;
import com.db4o.query.Query;
import sad.modelo.Disciplina;
import sad.modelo.Professor;
import sad.util.Constantes;
import sad.util.DAOEvent;
import sad.visao.DisciplinaTableModel;

public class DisciplinaTableDAO extends AbstractDAO {
    
  private static DisciplinaTableDAO INSTANCE=null;
  private static DisciplinaTableModel tableModel;
  private static int indexDisc;
  
  public static DisciplinaTableDAO getInstance(){
        if (DisciplinaTableDAO.INSTANCE ==null){
            DisciplinaTableDAO.INSTANCE = new DisciplinaTableDAO();
        }
        return DisciplinaTableDAO.INSTANCE;
    }
    
  //C(reate)R(etrieve)U(pdate)D(elete)

  public static void createTableDisc(){
      //Cria uma nova tabela de disciplinas
        tableModel = new DisciplinaTableModel();
        Query query = DAO.getObjectContainer().query();
        //Faz a busca no DAO e organiza pelo nome
        query.constrain(Disciplina.class);
        query.descend("nome").orderAscending();
        ObjectSet produtoList = query.execute();
        //add todos as disciplinas na tabela
        while(produtoList.hasNext()) {
            Disciplina proto = (Disciplina)produtoList.next();
            tableModel.addDisciplina(proto);
        }
        //organiza pelo nome
        tableModel.sortByNome();
  }
  
  public void create(String nome, 
                           String ab,
                           Professor prof){
        //Cria uma nova disciplina com os dados
        Disciplina d = new Disciplina();
        d.setNome(nome);
        d.setAbrev(ab);
        d.setProf(prof);
        //Se foi tudo criado e armazenado OK no Banco, add Disc na tabela
        if(DAO.create(d)){
            addDisciplina(d);
        }else{
            //avisa que deu problema no Banco
            DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                    new DAOEvent(d.getNome(), DAOEvent.DAO_NOCREATE));
        }
    }
  
    public void addDisciplina(Disciplina d) {
        //verifica se o primeiro professor foi adicionado e avisa aos ouvintes
        //sadgui deve habilitar menu topico
        int size = DAO.getListObjects(d).length;
        if(size==1){
                ProfessorTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                    new DAOEvent(Constantes.TOPICO, DAOEvent.DAO_FIRST));
        }
        //se existe uma tabela
        if (tableModel!=null){
            //add prof
            tableModel.addDisciplina(d);
            //organiza pelo nome
            tableModel.sortByNome();
        }
        //avisa aos ouvintes que um professor foi criado com sucesso
            DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                    new DAOEvent(d, d.getAbrev(), DAOEvent.DAO_CREATE));
    }
    
    public boolean isExist(String nome, String abrev, Professor p) {
        boolean existe = false;
        Disciplina proto = new Disciplina();
        proto.setAbrev(abrev);
        Disciplina d = (Disciplina)DAO.retrieve(proto);
        //Se não existe a disciplina, verifica se nao duplicada para o mesmo prof
        if(d != null){
             existe =true;
             DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                    new DAOEvent(abrev, DAOEvent.DAO_EXISTE));
        }else{
            proto = new Disciplina();
            proto.setNome(nome);
            Disciplina dset = (Disciplina)DAO.retrieve(proto);
            if(dset==null){
                existe = false;
            }else {
                if (dset.getProf().getNome().equals(p.getNome())){
                    existe =true;
                    DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                        new DAOEvent(nome, DAOEvent.DAO_EXISTE));
                }else {
                    existe =false;
                }
            }
        }
        return existe;
     }
    
     public static Disciplina getDisciplinaSaved(String ab) {
        Disciplina proto = new Disciplina();
        proto.setAbrev(ab);
        return (Disciplina) DAO.retrieve(proto);
     }
     
    public DisciplinaTableModel getTableDisciplina() {
        return tableModel;
    }
    //TODO remover Disciplina -> Topicos -> Subtopicos Relacionados
    public void removeDisciplina() {
        Disciplina d = tableModel.getDisciplina(getIndexDisc());
        TopicoTableDAO.getInstance().removeAllTopico(d);
        DisciplinaTableDAO.getInstance().delete(d);
        tableModel.removeDisciplina(getIndexDisc());
        //verifica se todos os professores foram apagados 
        //avisa para GUI desabilidar menu tópico
        if(tableModel.getRowCount()==0){
            DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                    new DAOEvent(Constantes.TOPICO, DAOEvent.DAO_NULL));
        }
        //avisa aos ouvintes da lista que um professor foi apagado
        DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                new DAOEvent(d, DAOEvent.DAO_DELETE));
    }

    public void setIndexDisc(int index) {
        //seta o index da disc selecionado na tabela
        indexDisc=index;
    }
    
    public int getIndexDisc() {
        //retorna o index da disc selecionada na tabela
        return indexDisc;
    }
    
    public void update(Disciplina d){
       //atualiza o banco (create igual a update)
        if(DAO.create(d)){
            //atualiza os valores editados na tabela
            tableModel.setValueAt(d, getIndexDisc(), 0);
            tableModel.setValueAt(d, getIndexDisc(), 1);
            tableModel.setValueAt(d, getIndexDisc(), 2);
            tableModel.sortByNome();
            //avisa a gui da atualização
            DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                    new DAOEvent(d.getAbrev(), DAOEvent.DAO_UPDATE));
        }else{
            DisciplinaTableDAO.getInstance().getSuporteEventos().disparaDAOEvento(
                    new DAOEvent(d.getAbrev(), DAOEvent.DAO_NOCREATE));
        }
    }
}